package qi
import (
    "bytes"
    "crypto/aes"
    "fmt"
    "crypto/cipher"
    "encoding/base64"
)

//密钥 长度必须 16/24/32长度
func Jm_加密(被加密文本 string, 密钥 string) string {
    // 转成字节数组
    origData := []byte(被加密文本)
    k := []byte(密钥)

	// 分组秘钥
	block, err := aes.NewCipher(k)
	if err != nil {
		panic(fmt.Sprintf("密钥 长度必须 16/24/32长度: %s", err.Error()))
	}
    // 获取秘钥块的长度
    blockSize := block.BlockSize()
    // 补全码
    origData = PKCS7Padding(origData, blockSize)
    // 加密模式
    blockMode := cipher.NewCBCEncrypter(block, k[:blockSize])
    // 创建数组
    cryted := make([]byte, len(origData))
    // 加密
    blockMode.CryptBlocks(cryted, origData)
    //使用RawURLEncoding 不要使用StdEncoding
    //不要使用StdEncoding  放在url参数中回导致错误
    return base64.RawURLEncoding.EncodeToString(cryted)

}
//密钥 长度必须 16/24/32长度
func Jm_解密(被解密文本 string, 密钥 string) string {
    //使用RawURLEncoding 不要使用StdEncoding
    //不要使用StdEncoding  放在url参数中回导致错误
    crytedByte, _ := base64.RawURLEncoding.DecodeString(被解密文本)
    k := []byte(密钥)

	// 分组秘钥
	block, err := aes.NewCipher(k)
	if err != nil {
		panic(fmt.Sprintf("密钥 长度必须 16/24/32长度: %s", err.Error()))
	}
    // 获取秘钥块的长度
    blockSize := block.BlockSize()
    // 加密模式
    blockMode := cipher.NewCBCDecrypter(block, k[:blockSize])
    // 创建数组
    orig := make([]byte, len(crytedByte))
    // 解密
    blockMode.CryptBlocks(orig, crytedByte)
    // 去补全码
    orig = PKCS7UnPadding(orig)
    return string(orig)
}

//补码
func PKCS7Padding(ciphertext []byte, blocksize int) []byte {
    padding := blocksize - len(ciphertext)%blocksize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(ciphertext, padtext...)
}

//去码
func PKCS7UnPadding(origData []byte) []byte {
    length := len(origData)
    unpadding := int(origData[length-1])
    return origData[:(length - unpadding)]
}

